#include <unistd.h>
#include <cstdio>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include "Task.hpp"
#include <vector>
#include <cstring>
#include <sys/types.h>
#include <sys/wait.h>
std::vector<task_t> tasks;
const int processnum = 10;

class channel
{
public:
    channel(int cmdfd, pid_t slaverid,const std::string &processname)
    :_cmdfd(cmdfd)
    ,_slaverid(slaverid)
    ,_processname(processname)
    {}
public:
    int _cmdfd;                //发送任务的文件描述符
    pid_t _slaverid;           //子进程PID
    std::string _processname;  //子进程的名字--方便打印日志 
};

void Slaver()
{
    
    while(true)
    {
        int cmdcode = 0;
        int n = read(0,&cmdcode,sizeof(int));

        if(n == sizeof(int))
        {
            std::cout<<"slaver say@ get a command: "<< 
            getpid() << " : cmdcode: " <<  cmdcode << std::endl;
            if(cmdcode >= 0 && cmdcode < tasks.size()) tasks[cmdcode]();
        }
        if(n == 0)break;   
    }
}


void InitProcessPool(std::vector<channel> *channels)
{
    for(int i = 0; i < processnum; i++)
    {
        int pipefd[2];
        int n = pipe(pipefd);
        assert(!n);
        (void)n;

        pid_t id = fork();
        if(id == 0)
        {
            //child 只读
            close(pipefd[1]);
            dup2(pipefd[0],0);
            close(pipefd[0]);
            Slaver();
            std::cout<<"process : "<<getpid() << " quit"
            <<std::endl;
            exit(0);
        }
            //parent 只写
        close(pipefd[0]);
        std::string name = "process-" + std::to_string(i);
        channels->push_back(channel(pipefd[1],id,name));
    }
}
void Menu()
{
    std::cout << "################################################" << std::endl;
    std::cout << "# 1. 刷新日志             2. 刷新出来野怪        #" << std::endl;
    std::cout << "# 3. 检测软件是否更新      4. 更新用的血量和蓝量  #" << std::endl;
    std::cout << "#                         0. 退出               #" << std::endl;
    std::cout << "#################################################" << std::endl;
}

void ctrlSlaver(const std::vector<channel> &channels)
{
    int which = 0;
    while(true)
    {
        int select = 0;
        Menu();
        std::cout << "Please Enter@ ";
        std::cin >> select;

        if(select <= 0 || select >= 5) break;

        int cmdcode = select - 1;

        std::cout << "father say: " << " cmdcode: " <<
            cmdcode << " already sendto " << channels[which]._slaverid << " process name: " 
                << channels[which]._processname << std::endl;

        write(channels[which]._cmdfd, &cmdcode,sizeof(cmdcode));
        which++;
        which %= channels.size();

        sleep(1);
    }
}

void QuitProcess(const std::vector<channel> &channels)
{
    for(const auto &c : channels)
    {
        close(c._cmdfd);
        waitpid(c._slaverid,nullptr,0);
    }
}



int main()
{
    LoadTask(&tasks);
    // 1.创建一批进程

    std::vector<channel> channels;

    InitProcessPool(&channels);
    
    ctrlSlaver(channels);

    QuitProcess(channels);
    return 0;
}